#ifndef __bot
#define __bot

#include <string>
#include <list>
#include <boost/date_time/posix_time/posix_time.hpp>

struct bot;
struct basic_viewer;

struct comparer { // for comparing prices based on bot's operation ie BUY or SELL.
  int exec;
  comparer (int _exec) : exec (_exec) {}
  int operator() (double price1, double price2);
};

struct trade { // trade info
  
  double price; // price at execution
  int size; // size of execution
  double secs; // time stamp
  double nor_pos; // normalised position (0 to 100%)
  double nor_time; // normalised time at execution (0 to 1)
  
  trade (double _p = 0, double _s = 0,  double _t = 0) {
    price = _p;
    size = _s;
    secs = _t;
    nor_pos = nor_time = 0;
  }
};

struct trade_i { // trade params interface; implemented by all derived bots 
  virtual int get_trade_size (double t) = 0;
  virtual double get_trade_interval () = 0;
};

typedef std::list<trade>::iterator trade_iterator;

struct bot : trade_i { // abstract bot
  
  std::string name; // name of the bot
  
  int state; // state of the bot
  enum {off, on, stopped, finished}; // bot's states

  std::string symbol; // stock symbol the bot works on
  
  double start_time, end_time; // start and end time of bot's activity
  double avail_time; // available time for the bot to make trades
  double avail_time_1; // inverse of available time
  boost::posix_time::ptime startt, endt; // start & end time of activity as boost ptime
  boost::posix_time::time_duration availd; // duration of bot activity as boost time_duration
        
  double stop_price; // price at which to stop executing (ie stop buy if  price >= stop_price, stop sell if price <= stop_price)
  double finish_price; // price at which to finish executing (ie buy out if price <= finish_price or sell out when price >= finish_price) 
  comparer cmp; // to decide execution based on buy or sell, stop_price & finish_price
  
  enum {buy = 0, sell}; // execution types
  int exec; // execution: buy or sell
  int num_shares; // number of shares to execute

  std::list<trade> trades; // list of all trades made
  int num_trades; // number of trades made
  trade last_trade; // last trade
  
  void execute (double price, int size, double secs); // executes trade
    
  // position entered (if its a buy bot) or closed (if its a sell bot) 
  //
  int position; // size of position
  double value; // value of position
  
  bot (const std::string& _name, const std::string& _symbol, int hs, int ms, int ss, int he, int me, int se, int _exec, int _num_shares, double _finish_price, double _stop_price);
  
  virtual ~bot () {}

  virtual int run (double secs); // runs the bot; bot waits for its time and executes
  
  basic_viewer* pviewer; // for visualisation
  
};

#endif
